define([ "Zepto", 
         "underscore", 
         "Backbone", 
         "views/homepage/homepage",
		"views/register/registerview", 
		"views/explore/exploreview",
		"views/faculty/facultylistpage", 
		"views/teacher/teacherpage",
		"views/pagep/studentpagep",
		"views/pagep/teacherpagep",
		"views/course/coursepage",
		"views/faculty/guidefacultypage",
		"views/hall/aulapage",
		"views/university/mappage",
		"views/university/universitylistpage",
		"views/corsolaurea/corsolaureapage",
		"views/vote/voteview", 
		"views/student/librettoview",
		"views/hall/searchhallview",
		"views/teacher/newnotice",
		"views/teacher/addcourse",
		"views/teacher/editappointmentview",
		"models/utente", 
		"models/corso",
		"models/aula",
		"models/universita",
		"models/facolta",
		"models/avviso",
		"models/corsolaurea",
		"models/ricevimentodocente",
		"models/studentevotacorso",
		"models/session",
		"models/corsostudente",
		"collections/utentecollection",
		"collections/corsostudentecollection",
		"collections/universitacollection",
		"collections/facoltacollection" ], function($, _, Backbone,
		HomePage, RegisterView, ExploreView, FacultyListPage, TeacherPage, StudentPageP, TeacherPageP, CoursePage, GuideFacultyPage, AulaPage, MapPage,
		UniversityListPage, CorsolaureaPage, VoteView, LibrettoView, SearchHallView, NewNotice, AddCourse, EditAppointmentView, Utente, Corso, Aula, Universita, Facolta, 
		Avviso, Corsolaurea, Ricevimentodocente, Studentevotacorso,
		Session, Corsostudente, UtenteCollection, CorsoStudenteCollection, UniversitaCollection, FacoltaCollection) {

	var AppRouter = Backbone.Router.extend({

		routes : {
			"" : "showHomePage",
			"homepage" : "showHomePage",
			"register" : "register",
			"explore" : "explore",
			"facultylist/:id" : "facultylist",
			"user/:id": "userDetails",
			"new-notice/:id": "newnotice",
			"edit-appointment/:id": "editappointment",
			"addcourse/:id": "addcourse",
			"courses/:id" : "courseDetails",
			"terminatecourse/:id": "terminatecourse",
			"hall/:id": "hallDetails",
			"zonaUniversity/:id": "zonaUniversity",
		    "searchHall": "searchHall",
		    "universitylist": "universitylist",
		    "guide/:id": "guide",
		    "infoLaurea/:id": "infoLaurea",
		    "logout": "logout",
		    "libretto": "libretto",
		    "addlibretto/:id": "addlibretto",
		  
		    "vote/:id": "vote",
		},

		initialize : function() {
		
			/*// SAVE
			 * var ada = new Utente({nome: "Ada", matricola:"222222"});
			 * ada.save();
			 */

			
			  // RECUPERO ISTANZA E UPDATE
			// dovrebbe recuperare un istanza e aggiornarla: funziona ma debbo
			// specificare suo id
			/*
			 var item = new Utente({objectId: 'HQgiMg8xc1'}); item.fetch();
			 item.save({nome: "jjjjjjjjjjjjjj"});
			*/
			
			// Inizializza la sessione
            var that = this;
			// Bind to the Session auth attribute so we
			// make our view act recordingly when auth changes
			Session.on('change:auth', function (session) {
			  that.showHomePage();
			});
			
		},

		showHomePage : function() {
			var self = this;
			if(Session.getAuth()){
				// alert('authed');
				var user = new Utente(Session.getAuth());
				if(Session.getAuth().isdocente){
					self.changePage(new TeacherPageP({ model: user }));
				}
				else{
					self.changePage(new StudentPageP({ model: user }));
				}
					

			} else {
				// alert('NOT authed');
				self.changePage(new HomePage());
			}
		},

		register : function() {
			var page = new RegisterView();
			this.changePage(page);
		},

		pwdrecover : function() {
			var page = new PwdrecoverView();
			this.changePage(page);
		},

		explore : function() {
			var page = new ExploreView();
			this.changePage(page);
		},

		facultylist : function(id) {
			self = this;
			
			var facList = new FacoltaCollection();
			
			if (navigator.geolocation) {
				var location_timeout = setTimeout("geolocFail()", 10000);
				navigator.geolocation.getCurrentPosition(
						function(position) {
							
							clearTimeout(location_timeout);
							var lat = position.coords.latitude;
							var lng = position.coords.longitude;
							function calculateDistance(lat1, lon1, lat2, lon2) {
								var R = 6371; // km
								var dLat = lat2-lat1;
								dLat = dLat*Math.PI/180;
								var dLon = lon2 - lon1;
								dLon = dLon*Math.PI/180;
								lat1R = lat1*Math.PI/180;
								lat2R = lat2*Math.PI/180;
								var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
								Math.cos(lat1R) * Math.cos(lat2R) * 
								Math.sin(dLon / 2) * Math.sin(dLon / 2); 
								var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
				    
								var d = R * c;
								return d;	  
							}   
							facList.fetch({
								query : {
									// seleziona le facoltà dell'università specificata
									//id_universita: id
									universita: {"__type":"Pointer","className":"universita","objectId":id}
								},
								success: function(data) {
									//var univ = new Universita({objectId: id}); 
									//univ.fetch();
									data.each(function(fac){ 
										var dist = calculateDistance(lat, lng, fac.get("latitudine"), fac.get("longitudine"));
										fac.set({distanza: dist});
										//alert(dist);
										
									});
									// in FacoltaCollection ho definito un metodo Comparator
									// ordino la lista delle facoltà in base alla distanza più vicina all'utente
									data.sort(data.comparator);
									self.changePage(new FacultyListPage({		
										model: data   				
									}));
								}
							});
						}, function(error) {
							clearTimeout(location_timeout);
						});
			} else {
				alert("Your browser or device doesn't support Geolocation");	
			}	
		},
		
		guide: function(id) {	
			var fac = new Facolta({objectId: id}); 
			var self = this;
			fac.fetch({
                success: function(data) {
                			 self.changePage(new GuideFacultyPage({
                		     model: data
                		}));
                }
            });
		},

		userDetails : function(id) {
			var user = new Utente({objectId: id}); 
			var self = this;

			user.fetch({
				include: 'facolta.universita',
                success: function(data) {
                	if(user.get("isdocente")){
						self.changePage(new TeacherPage({
						   model: data
						}));
                	} else {
                		alert ('StudentPage()');
                	}
                }
            });
		},
		
		newnotice: function(id) {
			var user = new Utente({objectId: id}); 
			var self = this;
			user.fetch({
                success: function(data) {
                	self.changePage(new NewNotice({
                		model: data
                	})); 	
                }
            });
		},
		
		editappointment: function(id) {
			//alert('editappointment');
			var user = new Utente({objectId: id}); 
			var self = this;
			// mettere un controllo isdocent
			user.fetch({
				include: 'ricevimento',
                success: function(data) {
                	// Se il ricevimento non esiste, lo crea
                	if(!data.get('ricevimento')) {
                		// Creo ricevimento vuoto
			            var ricevimento = new Ricevimentodocente();
			            ricevimento.save({},{
			                success: function(data, response) {
			                    // Salva nell'utente corrente, il puntatore al ricevimento appena creato
			                    $.ajax({
					                url: 'https://api.parse.com/1/users/'+id,
					                type: 'PUT',
					                dataType: 'json',
					                contentType: 'application/json',
					                data: '{"ricevimento": {"__type":"Pointer","className":"ricevimentodocente","objectId":"'+response.objectId+'"}}',
					                headers : {
					                  "X-Parse-Application-Id" : "0dIPUo9QsGjbp2G0H8qXB7tn8kqSSR6GiGkFm75x",
					                  "X-Parse-REST-API-Key" : "MIOI1uSRp8INLA9C7BFKSBRdimGN3fJvkY8me62r",
					                  "X-Parse-Session-Token" : Session.getAuth().sessionToken
					                },
					                success: function(data, status, xhr) { 
					                  //alert(xhr.status);
					                  //alert(xhr.responseText);
					                },    
					                error: function(xhr, errorType, error) {
					                  //alert(xhr.status);
					                  alert(xhr.responseText);
					                }
					            });


			                    // Apre la view passandogli solo l'objectId del ricevimento creato
			                    var ric = new Ricevimentodocente({ objectId: response.objectId });
			                	self.changePage(new EditAppointmentView({
			                		model: ric
			                	})); 
			                },
			                error: function(model, response) {
			                	alert('error: ' + response);
			                }
			            });
                	} else {
                		// Se il ricevimento esisteva già, apre la View passandogli i dati correnti
                		var idr = data.get('ricevimento').objectId;
                	
	                	var ric = new Ricevimentodocente({
	                		objectId: idr,
	                		maxprenotazioni: data.get('ricevimento').maxprenotazioni,
	                		orainizio: data.get('ricevimento').orainizio,
	                	    orafine: data.get('ricevimento').orafine,
	                	    stanza: data.get('ricevimento').stanza,
	                	    weekday: data.get('ricevimento').weekday
	                	});
	                	
	                	self.changePage(new EditAppointmentView({
	                		model: ric
	                	})); 
                	}

                	
                	
                }
            });
		},

		addcourse: function(id) {
			var user = new Utente({objectId: id}); 
			var self = this;
			user.fetch({
                success: function(data) {
                	self.changePage(new AddCourse({
                		model: data
                	})); 	
                }
            });
		},
		
		courseDetails: function(id) {
			var course = new Corso({objectId: id}); 
			var self = this;
		
			course.fetch({
				include : 'docente',          //Include un oggetto di tipo Puntatore
                success: function(data) {
                			 self.changePage(new CoursePage({
                		     model: data
                		}));
                }
            });
		},
		
		terminatecourse: function(id) {
			var course = new Corso({objectId: id}); 
			
			var self = this;
			// recupera il corso da disattivare
			course.fetch();
			var namecourse = course.get('nome');
			// mi da UNIFIED il nome corso!!!
			//alert(namecourse);
			// disattiva il corso
			course.save({
            	isattivo: false
            },{
            	success: function(){
            		$('#bottommenu').empty();
	            	// crea un avviso
	            	var testo = "Il corso è terminato. Prof. " + Session.getAuth().nome + " " + Session.getAuth().cognome;
	            	alert('Il corso è terminato');
	            	
	            	var notice = new Avviso({
	            		testo: testo,
	            		corso: {"__type":"Pointer","className":"corso","objectId":id}
	            	});
	            	notice.save();
            	
            	},
            	error: function(){
            	//	alert('error ');
            	}
            	
            });
			// this.showHomePage();
		}, 
		
		searchHall : function() {
			var page = new SearchHallView();
			this.changePage(page);
		},
		
		libretto: function(){
			var page = new LibrettoView();
			this.changePage(page);
		},
		
		addlibretto: function(id){
			var user = new Utente(Session.getAuth());
			var user_id = user.get('objectId');
			var corsostud; 

			this.corsostudenteCollection = new CorsoStudenteCollection();
			this.corsostudenteCollection.fetch({
				query : {
					// verifico se il corso non è già stato aggiunto nel libretto
					libretto: false,
					terminato: true,
					utente: {"__type":"Pointer","className":"_User","objectId":user_id} ,
					corso: {"__type":"Pointer","className":"corso","objectId":id}
				},
			//	include:'corso',
				success: function(data) {
					// esiste un record relativo al corso in questione seguito da utente ma NON nel libretto
					// lo aggiungo
					if(data.length > 0){
						//alert('data.length > 0 ');
						corsostud = new Corsostudente({objectId: data.models[0].get('objectId')});
						corsostud.fetch();
						corsostud.save({
							libretto: true,
							votazione: 0
			            },{
			            	success: function(){
			            		//alert('corsostudente aggiornato: inserimento libretto');
			            	}
			            });
					}else{
						//alert('data.length = 0 ');
						corsostud = new Corsostudente();
						corsostud.save({
							libretto: true,
							utente: {"__type":"Pointer","className":"_User","objectId":user_id} ,
							corso: {"__type":"Pointer","className":"corso","objectId":id},
							notifica: false,
							terminato: true,
							votazione: 0
			            },{
			            	success: function(){
			            		alert('Il corso è stato inserito nel libretto');
			            	}
			            });
						
					}
					$('#bottommenu').empty();
				}});
		},
		
	
		hallDetails: function(id) {
			var hall = new Aula({objectId: id});
			var self = this;
			hall.fetch({
                success: function(data) {
                	self.changePage(new AulaPage({
                		     model: data
                		}));
                }
            });
		},
		
		universitylist : function() {
			
			self = this;
			var uniList = new UniversitaCollection();
			if (navigator.geolocation) {
				
			    var location_timeout = setTimeout(" ", 10000);
			    navigator.geolocation.getCurrentPosition(
			    		function(position) {
			        clearTimeout(location_timeout);
			        var lat = position.coords.latitude;
			        var lng = position.coords.longitude;
			        function calculateDistance(lat1, lon1, lat2, lon2) {
			        	  var R = 6371; // km
			        	  var dLat = lat2-lat1;
			        	  dLat = dLat*Math.PI/180;
			        	  var dLon = lon2 - lon1;
			        	  dLon = dLon*Math.PI/180;
			        	  lat1R = lat1*Math.PI/180;
			        	  lat2R = lat2*Math.PI/180;
			        	  var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
			        	          Math.cos(lat1R) * Math.cos(lat2R) * 
			        	          Math.sin(dLon / 2) * Math.sin(dLon / 2); 
			        	  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
			        	  var d = R * c;
			        	  return d;	  
			        	 /* Number.prototype.toRad = function() {
				        	  return this * Math.PI / 180;
				        	}*/
			        }   
					uniList.fetch({
						query : {
							
						},
						success: function(data) {
							uniList.each(function(uni){ 
								var dist = calculateDistance(lat, lng, uni.get("latitudine"), uni.get("longitudine"));
								//uni.save({distanza: dist});
								uni.set({ distanza: dist });
							
							});
							// in UniversitaCollection ho definito un metodo Comparator
							// ordino la lista delle università in base alla distanza più vicina all'utente
							uniList.sort(uniList.comparator);
							/*uniList.each(function(uni){
								//alert('nome ' + uni.get('nome'));	
							});*/
							self.changePage(new UniversityListPage({		
								model: uniList    	
							}));
						}
					});
			    }, function(error) {
			        clearTimeout(location_timeout);
			    });
			}else{
				
			} 
			
		},
		
		zonaUniversity: function(id){
			var uni = new Universita({objectId: id});
				alert('zonaUniversity: ' + id);
				var self = this;
				uni.fetch({
	                success: function(data) {
	                	self.changePage(new MapPage({
	                		     model: data
	                		}));
	                }
	            });
		},
		
		infoLaurea: function(id) {
			var cl = new Corsolaurea({objectId: id});
				var self = this;
				cl.fetch({
	                success: function(data) {
	                	self.changePage(new CorsolaureaPage({
	                		     model: data
	                		}));
	                }
	            });
			},
		
		vote : function(id) {
			// passa come modello un Studentevotacorso vuoti relativo al corso
			var svc = new Studentevotacorso({
				corso: {"__type":"Pointer","className":"corso","objectId":id}
			});
			var page = new VoteView();
			this.changePage(new VoteView({
				model: svc
			}));
		},

		logout: function() {
            Session.logout();
		},

		changePage : function(page) {
			page.render();
			$('body').empty();
			$('body').append($(page.el));
			// Se la view ha la funzione postRender, chiamala.
			// E' utile in caso di utilizzo di Plugin come iScroll
			if (page.postRender) {
				page.postRender();
			}
		}

	});

	return AppRouter;

});